/*!
 * \file jxbankafanatp_message.c
 *
 * \brief JXBANKAFANATP消息解析
 * 
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.
 *
 * \version 1.0
 * \author songbb
 * \date 2017/04/20
 *
 */

#include <iconv2utf8.h>
#include <frreport_opt.h>
#include "conntrack.h"
#include "frct_comm.h"
#include "frreport_comm.h"

#include "jxbankafanatp_core.h"
#include "jxbankafanatp_comm.h"
#include "jxbankafanatp_message.h"

typedef struct __st_workcode_node {
    char *p_name;
} Jxbankafanatp_workcode;

typedef struct __st_jxbankafanatp_workcode_map
{
    char arr_code[9];
    char arr_name[50];
} Jxbankafanatp_workcode_map;

Jxbankafanatp_workcode_map arr_jxbankafanatp_workcode_maps[] = {
        {"EBONLQRY", "处理成功"},
        {"RCPERBOG", "接收队列中没有报文"},
        {"EBONLPAY", "收到待确认报文"},
        {"SBSSDXJK", "业务种类非法"},
        {"EBSCHBRN", "报文类型与业务类型不匹配"},
};

Frhash_header *p_hash_jxbankafanatp_workcode = NULL;

/*******************************************************************************
*  FUNC     :  释放 Jxbankafanatp_workcode
*  ARGS     :  **pp_st_workcode                             (Jxbankafanatp_workcode)
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC void __jxbankafanatp_free_workcode(Jxbankafanatp_workcode **pp_st_workcode)
{
    if (pp_st_workcode == NULL || *pp_st_workcode == NULL)
        return;

    jxbankafanatp_free((void **) &((*pp_st_workcode)->p_name));
    jxbankafanatp_free((void **) pp_st_workcode);

    return;
}

/*******************************************************************************
*  FUNC     :  释放 stmt node节点
*  ARGS     :  *p_st_node                               (Frlist_node)
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC void __jxbankafanatp_workcode_node_free(Frlist_node *p_st_node)
{
    if (p_st_node == NULL || p_st_node->data == NULL)
        return;

    Jxbankafanatp_workcode *p_st_sip_stmt = (Jxbankafanatp_workcode *) FRLIST_GET_NODE_DATA(p_st_node);
    __jxbankafanatp_free_workcode(&p_st_sip_stmt);
    p_st_node->data = NULL;
}

void jxbankafanatp_init_hash_workcode(void)
{
    int len = sizeof(arr_jxbankafanatp_workcode_maps) / sizeof(arr_jxbankafanatp_workcode_maps[0]);
    int i_loop = 0;
    Jxbankafanatp_workcode *p_st_workcode = NULL;
    Frlist_node *p_st_node = NULL;

    p_hash_jxbankafanatp_workcode = frhash2_create2(len);

    for (; i_loop < len; i_loop++)
    {
        if ((p_st_workcode = (Jxbankafanatp_workcode *) frmalloc(sizeof(Jxbankafanatp_workcode))) == NULL)
        {
            JXBANKAFANATP_MALLOCK_ERR;
            return;
        }
        memset(p_st_workcode, 0x00, sizeof(Jxbankafanatp_workcode));

        p_st_workcode->p_name = frstrdup(arr_jxbankafanatp_workcode_maps[i_loop].arr_name);
        p_st_node = frlist_node_create(p_st_workcode);

        if (frhash2_addStr(p_hash_jxbankafanatp_workcode, arr_jxbankafanatp_workcode_maps[i_loop].arr_code,
                           (unsigned int) strlen(arr_jxbankafanatp_workcode_maps[i_loop].arr_code), p_st_node) != FR_SUCC)
        {
            __jxbankafanatp_free_workcode(&p_st_workcode);
            __jxbankafanatp_workcode_node_free(p_st_node);
            return;
        }
    }

    return;
}

void jxbankafanatp_destroy_hash_workcode(void)
{
    frhash2_free2(p_hash_jxbankafanatp_workcode, __jxbankafanatp_workcode_node_free);
    return;
}

int jxbankafanatp_req(Conntrack *p_st_conn
                    , L7session_jxbankafanatp *p_st_sess
                    , L7_jxbankafanatp_packet *p_st_jxbankafanatp_packet
                    , Frhash_header *p_st_hash_report)
{
    JXBANKAFANATP_PRINT_INFO("jxbankafanatp_req...\n");
    Frreport_body_data *p_st_body = NULL;
    Jxbankafanatp_workcode *p_st_workcode = NULL;
    Frlist_node *p_st_node = NULL;
    unsigned char uc_version = 0;
    char arr_transcode[20+1] = {0};
    unsigned char uc_len = 0;
    unsigned int ui_len = 0;
    char *p_key = NULL;
    char *p_value = NULL;
    char *p_value_utf8 = NULL;
    unsigned int ui_value_len = 0;
    char *p_field_name = NULL;
    int i_field_name_len = 0;

    if (bytebuffer_get_at(p_st_jxbankafanatp_packet->p_st_packet, 10, &uc_version) != FR_SUCC)
        goto error;

    JXBANKAFANATP_PRINT_INFO("Version:[0x%02x]\n", uc_version);

    if (uc_version != 0x10 && uc_version != 0x30)
    {
        JXBANKAFANATP_PRINT_EMERG("unknown Version\n");
        goto error;
    }

    if (bytebuff_skip(p_st_jxbankafanatp_packet->p_st_packet, 11) != FR_SUCC)
        goto error;

    memset(arr_transcode, 0x00, sizeof(arr_transcode));
    if (bytebuff_get_bytes(p_st_jxbankafanatp_packet->p_st_packet, arr_transcode, 20) != FR_SUCC)
        goto error;
    frtrim(arr_transcode);
    JXBANKAFANATP_PRINT_WARN("req TransCode:[%s]\n", arr_transcode);

    // 新建上报数据结构体
    if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
        goto error;

    if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".type_code", arr_transcode) != FR_SUCC)
        goto error;

    p_st_node = frhash2_getStr(p_hash_jxbankafanatp_workcode, arr_transcode, (unsigned int) strlen(arr_transcode));

    if (p_st_node && (p_st_workcode = (Jxbankafanatp_workcode *) FRLIST_GET_NODE_DATA(p_st_node)) == NULL)
        goto error;
    if (p_st_workcode && p_st_workcode->p_name)
    {
        if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS_TITLE, p_st_workcode->p_name) != FR_SUCC)
            goto error;
        if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".type_name", p_st_workcode->p_name) != FR_SUCC)
            goto error;
    }
    else
    {
        if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS_TITLE, arr_transcode) != FR_SUCC)
            goto error;
        if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_TRANS".type_name", arr_transcode) != FR_SUCC)
            goto error;
    }

    if (bytebuff_setPosition(p_st_jxbankafanatp_packet->p_st_packet, APM_JXBANKAFANATP_HDR_LEN) != FR_SUCC)
        goto error;

    while (bytebuff_remaining(p_st_jxbankafanatp_packet->p_st_packet) > 4)
    {
        if (uc_version == 0x10)
        {

        }
        else // 0x30
        {
            if (bytebuff_get_char(p_st_jxbankafanatp_packet->p_st_packet, &uc_len) != FR_SUCC)
                goto error;

            if ((p_key = (char *) frmalloc((uc_len + 1) * sizeof(char))) == NULL)
            {
                JXBANKAFANATP_MALLOCK_ERR;
                goto error;
            }
            memset(p_key, 0x00, uc_len + 1);

            if (bytebuff_get_bytes(p_st_jxbankafanatp_packet->p_st_packet, p_key, uc_len) != FR_SUCC)
                goto error;
            p_key[uc_len] = '\0';

            i_field_name_len = (int) strlen("request.jxbank_afanatp.") + uc_len + 1;

            if (bytebuff_get_int(p_st_jxbankafanatp_packet->p_st_packet, 4, &ui_len, BYTE_BIG_ENDIAN) != FR_SUCC)
                goto error;

            if ((p_value = (char *) frmalloc((ui_len + 1) * sizeof(char))) == NULL)
            {
                JXBANKAFANATP_MALLOCK_ERR;
                goto error;
            }
            memset(p_value, 0x00, ui_len + 1);
            if (bytebuff_get_bytes(p_st_jxbankafanatp_packet->p_st_packet, p_value, ui_len) != FR_SUCC)
                goto error;
            p_value[ui_len] = '\0';

            if (iconv_to_utf8(p_value, strlen(p_value), "gb18030", &p_value_utf8, &ui_value_len) != FR_SUCC)
                goto error;
            frtrim(p_value_utf8);
        }

        if ((p_field_name = (char *) frmalloc((i_field_name_len + 1) * sizeof(char))) == NULL)
        {
            JXBANKAFANATP_MALLOCK_ERR;
            goto error;
        }
        memset(p_field_name, 0x00, i_field_name_len + 1);
        snprintf(p_field_name, i_field_name_len, "request.jxbank_afanatp.%s", p_key);

        if (p_value_utf8 == NULL)
            p_value_utf8 = frstrdup("");

        JXBANKAFANATP_PRINT_WARN("[%s] = [%s]\n", p_field_name, p_value_utf8);

        if (frreport_body_l7_add_str(p_st_body, p_field_name, p_value_utf8) != FR_SUCC)
            goto error;

        jxbankafanatp_free((void **) &p_key);
        jxbankafanatp_free((void **) &p_field_name);
        jxbankafanatp_free((void **) &p_value);
        jxbankafanatp_free((void **) &p_value_utf8);
    }

    // 上报数据
    if (jxbankafanatp_report_msg_data_req(p_st_conn, p_st_jxbankafanatp_packet, p_st_body, p_st_hash_report) != FR_SUCC)
        goto error;

    return FR_SUCC;
error:
    jxbankafanatp_free((void **) &p_key);
    jxbankafanatp_free((void **) &p_field_name);
    jxbankafanatp_free((void **) &p_value);
    jxbankafanatp_free((void **) &p_value_utf8);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}

int jxbankafanatp_resp(Conntrack *p_st_conn
                    , L7session_jxbankafanatp *p_st_sess
                    , L7_jxbankafanatp_packet *p_st_jxbankafanatp_packet
                    , Frhash_header *p_st_hash_report)
{
    JXBANKAFANATP_PRINT_INFO("jxbankafanatp_resp...\n");
    Frreport_body_data *p_st_body = NULL;
    unsigned char uc_version = 0;
    char arr_transcode[20+1] = {0};
    unsigned char uc_len = 0;
    unsigned int ui_len = 0;
    char *p_key = NULL;
    char *p_value = NULL;
    char *p_value_utf8 = NULL;
    unsigned int ui_value_len = 0;
    char *p_field_name = NULL;
    int i_field_name_len = 0;

    if (bytebuffer_get_at(p_st_jxbankafanatp_packet->p_st_packet, 10, &uc_version) != FR_SUCC)
        goto error;

    JXBANKAFANATP_PRINT_INFO("Version:[0x%02x]\n", uc_version);

    if (uc_version != 0x10 && uc_version != 0x30)
    {
        JXBANKAFANATP_PRINT_EMERG("unknown Version\n");
        goto error;
    }

    if (bytebuff_skip(p_st_jxbankafanatp_packet->p_st_packet, APM_JXBANKAFANATP_HDR_LEN) != FR_SUCC)
        goto error;

    memset(arr_transcode, 0x00, sizeof(arr_transcode));
    if (bytebuff_get_bytes(p_st_jxbankafanatp_packet->p_st_packet, arr_transcode, 20) != FR_SUCC)
        goto error;
    frtrim(arr_transcode);
    JXBANKAFANATP_PRINT_WARN("resp TransCode:[%s]\n", arr_transcode);

    // 新建上报数据结构体
    if ((p_st_body = frreport_body_new_l7(p_st_conn)) == NULL)
        goto error;

    if (bytebuff_setPosition(p_st_jxbankafanatp_packet->p_st_packet, APM_JXBANKAFANATP_HDR_LEN) != FR_SUCC)
        goto error;

    while (bytebuff_remaining(p_st_jxbankafanatp_packet->p_st_packet) > 4)
    {
        if (uc_version == 0x10)
        {

        }
        else // 0x30
        {
            if (bytebuff_get_char(p_st_jxbankafanatp_packet->p_st_packet, &uc_len) != FR_SUCC)
                goto error;

            if ((p_key = (char *) frmalloc((uc_len + 1) * sizeof(char))) == NULL)
            {
                JXBANKAFANATP_MALLOCK_ERR;
                goto error;
            }
            memset(p_key, 0x00, uc_len + 1);
            if (bytebuff_get_bytes(p_st_jxbankafanatp_packet->p_st_packet, p_key, uc_len) != FR_SUCC)
                goto error;
            p_key[uc_len] = '\0';

            i_field_name_len = (int) strlen("response.jxbank_afanatp.") + uc_len + 1;

            if (bytebuff_get_int(p_st_jxbankafanatp_packet->p_st_packet, 4, &ui_len, BYTE_BIG_ENDIAN) != FR_SUCC)
                goto error;

            if ((p_value = (char *) frmalloc((ui_len + 1) * sizeof(char))) == NULL)
            {
                JXBANKAFANATP_MALLOCK_ERR;
                goto error;
            }
            memset(p_value, 0x00, ui_len + 1);
            if (bytebuff_get_bytes(p_st_jxbankafanatp_packet->p_st_packet, p_value, ui_len) != FR_SUCC)
                goto error;
            p_value[ui_len] = '\0';

            if (iconv_to_utf8(p_value, strlen(p_value), "gb18030", &p_value_utf8, &ui_value_len) != FR_SUCC)
                goto error;
            frtrim(p_value_utf8);
        }

        if ((p_field_name = (char *) frmalloc((i_field_name_len + 1) * sizeof(char))) == NULL)
        {
            JXBANKAFANATP_MALLOCK_ERR;
            goto error;
        }
        memset(p_field_name, 0x00, i_field_name_len + 1);
        snprintf(p_field_name, i_field_name_len, "response.jxbank_afanatp.%s", p_key);

        if (p_value_utf8 == NULL)
            p_value_utf8 = frstrdup("");

        JXBANKAFANATP_PRINT_CRIT("[%s] = [%s]\n", p_field_name, p_value_utf8);

        if (frreport_body_l7_add_str(p_st_body, p_field_name, p_value_utf8) != FR_SUCC)
            goto error;

//        if (strcmp(p_key, "errorcode") == 0)
//        {
//            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_RESP_CODE_STRING, p_value_utf8) != FR_SUCC)
//                goto error;
//        }
//        else if (strcmp(p_key, "errormsg") == 0)
//        {
//            if (frreport_body_l7_add_str(p_st_body, APM_REPORT_KEY_RESP_ERR_MSG, p_value_utf8) != FR_SUCC)
//                goto error;
//        }

        jxbankafanatp_free((void **) &p_key);
        jxbankafanatp_free((void **) &p_field_name);
        jxbankafanatp_free((void **) &p_value);
        jxbankafanatp_free((void **) &p_value_utf8);
    }

    // 上报数据
    if (jxbankafanatp_report_msg_data_resp(p_st_conn, p_st_jxbankafanatp_packet, p_st_body, p_st_hash_report) != FR_SUCC)
        goto error;

    return FR_SUCC;
error:
    jxbankafanatp_free((void **) &p_key);
    jxbankafanatp_free((void **) &p_field_name);
    jxbankafanatp_free((void **) &p_value);
    jxbankafanatp_free((void **) &p_value_utf8);
    frreport_body_free(&p_st_body);
    return FR_FAIL;
}
